#include "CampaignSettingDataForm.h"
#include "ui_CampaignSettingDataForm.h"


#include <CharacterClass.h>
#include <FileHandler.h>
#include <XmlSerializer.h>


#include <QSortFilterProxyModel>
#include <QFileDialog>
#include <QMessageBox>
#include <QTimer>
#include <QDebug>



CampaignSettingDataForm::CampaignSettingDataForm(CampaignSetting* root, QWidget *parent) :
    QWidget(parent),
    ui(new Ui::CampaignSettingDataForm)
{
    m_actions = 0;
    m_model = new ItemModel(this);
    m_root = root;
    m_model->setRootItem(m_root);

    ui->setupUi(this);


    initializeActions();

    ui->treeViewCampaignSettingData->setModel(m_model);
    ui->treeViewCampaignSettingData->header()->setResizeMode(QHeaderView::ResizeToContents);


    m_dataModel = new QSortFilterProxyModel(this);
    m_dataModel->setSourceModel(m_model);
    m_dataModel->setFilterRole(Qt::EditRole);
    m_dataModel->setFilterKeyColumn(AbstractItem::IdData);
    ui->treeViewCharacterClassData->setModel(m_dataModel);

    m_selectionModel = new QSortFilterProxyModel(this);
    m_selectionModel->setSourceModel(m_model);
    m_selectionModel->setFilterRole(Qt::EditRole);
    m_selectionModel->setFilterKeyColumn(AbstractItem::IdData);
    m_selectionModel->setFilterRegExp("\\S\\.(?=(Skill|Feat))");

    QSortFilterProxyModel* comboBoxModel = new QSortFilterProxyModel(this);
    comboBoxModel->setSourceModel(m_model);
    comboBoxModel->setFilterRole(Qt::DisplayRole);
    comboBoxModel->setFilterKeyColumn(AbstractItem::CategoryData);
    comboBoxModel->setFilterFixedString("CharacterClass");
    ui->comboBoxCharacterClass->setModel(comboBoxModel);


    connect(m_root.data(), SIGNAL(sigDirty()), this, SLOT(onDirty()));
    onDirty();
}


CampaignSettingDataForm::~CampaignSettingDataForm()
{
    delete ui;
}


void CampaignSettingDataForm::onSave()
{
    onUpdateData();
    QString file_path = m_root->filePath();
    if (FileHandler::save(m_root.data(), file_path)) return;

    onSaveAs();
}


void CampaignSettingDataForm::onSaveAs()
{
    onUpdateData();
    QString file_path = QFileDialog::getSaveFileName(this, tr("Save Campaign Setting"), QDir::currentPath(), tr("Xml Files (*.xml)"));
    if (file_path.isEmpty()) return;

    if (FileHandler::save(m_root.data(), file_path)) return;

    QMessageBox::information(this, tr("Failed to Save File!"), QString("%1:\n'%2'!").arg(tr("Failed to save file to path")).arg(file_path));
}


void CampaignSettingDataForm::onClose()
{
    onUpdateData();
    if (!m_root->isDirty())
    {
        close();
        return;
    }

    switch (QMessageBox::question(this, tr("Save Changes?"), tr("File has been modified.\nDo you want to save file?"), QMessageBox::Yes | QMessageBox::No ))
    {
    case QMessageBox::Yes: onSave();
    }

    close();
}


void CampaignSettingDataForm::onUpdateData()
{
    // Add slot calls for each editing slot here
    // to update model before save, saveAs and close...
    on_lineEditName_editingFinished();
}


void CampaignSettingDataForm::onDirty()
{
    QString oldName = property(P_CAMPAIGN_NAME).toString();
    QString newName = m_root->name();
    if (oldName == newName) return;

    ui->lineEditName->setText(newName);
    setProperty(P_CAMPAIGN_NAME, newName);
    emit sigDirty();
}


void CampaignSettingDataForm::onActionTriggered(QAction* action)
{


    QModelIndex index = ui->treeViewCampaignSettingData->currentIndex();
    if (action == ui->actionRemove)
    {
        m_model->removeRows(index.row(), 1, index.parent());
        return;
    }

    int row = -1;
    if (action == ui->actionAdd_Item)
    {
        row = m_model->addItem(new ValueItem(tr("New Item")), index);
    }

    if (action == ui->actionAdd_Reference)
    {
        row = m_model->addItem(new ReferenceItem(), index);
    }

    if (action == ui->actionAdd_Character_Class)
    {
        index = QModelIndex();
        // deserialize resource content with xml serializer...
        XmlSerializer ser;
        QFile f(":/d20/CHARACTER_CLASS");
        if (!f.open(QFile::ReadOnly))
        {
            QMessageBox::information(this, tr("Failed to Open File!"), tr("Failed to open character template file!"));
            return;
        }

        CharacterClass* characterItem = dynamic_cast<CharacterClass*>(ser.deserialize(&f));
        f.close();
        if (!characterItem)
        {
            QMessageBox::information(this, tr("Unknown Xml Content!"), tr("Character template file has unknown file content!"));
            return;
        }

        row = m_model->addItem(characterItem, index);
    }

    if (row < 0) return;

    QModelIndex current = m_model->index(row, AbstractItem::NameData, index);
    ui->treeViewCampaignSettingData->setCurrentIndex(current);
    ui->treeViewCampaignSettingData->edit(current);
}


void CampaignSettingDataForm::initializeActions()
{
    if (m_actions) return;

    m_actions = new QActionGroup(this);

    m_actions->addAction(ui->actionAdd_Item);
    m_actions->addAction(ui->actionAdd_Reference);
    m_actions->addAction(ui->actionRemove);
    m_actions->addAction(ui->actionAdd_Character_Class);

//    actionGroup->addAction(ui->actionAdd_Character_Race);
//    actionGroup->addAction(ui->actionAdd_Monster);

    addActions(m_actions->actions());
    addAction(ui->actionNext_Page);
    addAction(ui->actionPrev_Page);
    connect(m_actions, SIGNAL(triggered(QAction*)), this, SLOT(onActionTriggered(QAction*)));
}

void CampaignSettingDataForm::on_lineEditName_editingFinished()
{
    QString name = ui->lineEditName->text();
    if (name.isEmpty())
    {
        QMessageBox::information(this, tr("Invalid Name"), tr("Campaign setting name can't be empty"));
        return;
    }

    m_root->setData(AbstractItem::NameData, name);
}



void CampaignSettingDataForm::on_actionNext_Page_triggered()
{
    if (ui->stackedWidget->count() <= 1) return;

    int next = ui->stackedWidget->currentIndex()+1;
    if (next >= ui->stackedWidget->count()) next = 0;

    ui->stackedWidget->setCurrentIndex(next);
}

void CampaignSettingDataForm::on_actionPrev_Page_triggered()
{
    if (ui->stackedWidget->count() <= 1) return;

    int prev = ui->stackedWidget->currentIndex()-1;
    if (prev < 0) prev = ui->stackedWidget->count()-1;

    ui->stackedWidget->setCurrentIndex(prev);
}

void CampaignSettingDataForm::on_comboBoxCharacterClass_currentIndexChanged(int)
{
    if (ui->comboBoxCharacterClass->count() <= 0) return;

//    m_dataModel->setFilterWildcard("*." + ui->comboBoxCharacterClass->currentText());
}

void CampaignSettingDataForm::on_comboBoxCharacterClass_currentIndexChanged(QString text)
{
    m_dataModel->setFilterWildcard(QString("*.%1").arg(text));
}
